const webpack = require("webpack"),
  path = require("path"),
  { getPackageName } = require("./utils/index"),
  HtmlWebpackPlugin = require("html-webpack-plugin"),
  { CleanWebpackPlugin } = require("clean-webpack-plugin"),
  MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = (env, argv) => {
  const { nodeEnv = "production" } = argv,
    packageName = getPackageName();

  const webpackConfig = {
    mode: nodeEnv,
    devtool: "source-map",
    entry: {
      index: `./src/${packageName}/index.ts`,
    },
    output: {
      path: path.join(__dirname, "dist"),
      filename: "./js/[name].[contenthash:8].js",
      chunkFilename: "./js/[name].[contenthash:8].chunk.js",
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [MiniCssExtractPlugin.loader, "css-loader"],
          exclude: /node_modules/,
        },
        {
          test: /\.scss$/,
          use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
          exclude: /node_modules/,
        },
        {
          test: /\.js$/i,
          loader: "babel-loader",
          exclude: /node_modules/,
          options: {
            presets: ["@babel/preset-env"],
          },
        },
        {
          test: /\.ts$/i,
          loader: "ts-loader",
          exclude: /node_modules/,
        },
        {
          test: /\.(gif|png|jpe?g|svg|xml)$/i,
          loader: "file-loader",
          options: {
            name: "./img/[name].[contenthash:5].[ext]",
          },
          exclude: /node_modules/,
        },
        {
          test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/i,
          loader: "file-loader",
          options: {
            name: "./media/[name].[contenthash:5].[ext]",
          },
          exclude: /node_modules/,
        },
      ],
    },
    resolve: {
      alias: {
        "@": path.join(__dirname, "src"),
      },
      extensions: [".tsx", ".ts", ".jsx", ".js"],
      symlinks: false,
    },
    plugins: [
      new webpack.ProgressPlugin(),
      new CleanWebpackPlugin(),
      new MiniCssExtractPlugin({
        filename: "./css/[name].[contenthash:5].css",
      }),
      new HtmlWebpackPlugin({
        title: "phaser3-game",
        chunks: ["index"],
        template: path.join(__dirname, "public", "index.html"),
      }),
      new webpack.HotModuleReplacementPlugin(),
    ],
    target: "web",
    devServer: {
      compress: true,
      host: "localhost",
      port: 8080,
      open: true,
    },
  };

  if (nodeEnv === "production") {
    const TerserPlugin = require("terser-webpack-plugin");

    webpackConfig.optimization = {
      minimize: nodeEnv === "production",
      minimizer: [new TerserPlugin()],
      splitChunks: {
        // all  对同步、异步代码都分割
        // async只对异步代码分割，如import('loadash')
        // initial只对同步代码分割，如import lodash from 'loadash'
        chunks: "all",
        cacheGroups: {
          // 第三方模块
          vendor: {
            // 每个分组的名字
            name: "vendor",
            chunks: "all",
            // 优先级，数字越大，越先处理
            priority: 1,
            // 匹配需要分割的模块
            test: /node_modules/,
            // 检测模块被引用次数，对于第三方模块而言，引用1次就应该单独打包，公共模块引用2次应该单独打包
            minChunks: 2,
          },
          // 公共模块
          common: {
            name: "common",
            chunks: "all",
            priority: 0,
            minChunks: 2,
          },
        },
      },
      runtimeChunk: {
        name: (entrypoint) => `runtime-${entrypoint.name}`,
      },
    };
  }
  return webpackConfig;
};
